//
//  FileWindow.cpp
//  Editor
//
//  Created by Jeppe Nielsen on 10/19/14.
//  Copyright (c) 2014 Jeppe Nielsen. All rights reserved.
//

#include "FileWindow.hpp"
#include "Project.hpp"
#include <QtCore/QtCore>
#include <iostream>

using namespace Qt;

std::string FileWindow::GetName() { return "Files"; }

void FileWindow::OnCreate() {

    CreateContextMenu();

    fileSystemModel = new QFileSystemModel(window);
    fileSystemModel->setReadOnly(false);
    
    
    treeView = new QTreeView(window);
    
    
    treeView->setModel(fileSystemModel);
    
    treeView->hideColumn(1);
    treeView->hideColumn(2);
    treeView->hideColumn(3);
    
    treeView->setSelectionMode(QAbstractItemView::SingleSelection);
    treeView->setSelectionModel(new QItemSelectionModel(fileSystemModel));

    treeView->setDragEnabled(true);
    treeView->setDragDropMode(QAbstractItemView::InternalMove);
    treeView->setEditTriggers(QAbstractItemView::NoEditTriggers);
    
    treeView->setContextMenuPolicy(Qt::CustomContextMenu);
    
    
    QSplitter* splitter = new QSplitter(Qt::Horizontal);
    
    splitter->addWidget(treeView);
    
    
    tabWidget = new QTabWidget;
    tabWidget->setTabsClosable(true);
    tabWidget->setMovable(true);
    tabWidget->setDocumentMode(true);
   
    connect(tabWidget, SIGNAL(tabCloseRequested(int)), this, SLOT(TabClosedClicked(int)));
    
    splitter->addWidget(tabWidget);
    
    window->setWidget(splitter);
    
    
    context->CurrentProject.Changed += event_handler(this, &FileWindow::ProjectChanged);
    
    connect(fileSystemModel, SIGNAL(fileRenamed(const QString&, const QString&, const QString&)), this, SLOT(FileRenamed(const QString&, const QString&, const QString&)));
    
    connect(treeView->selectionModel(), SIGNAL(currentChanged(const QModelIndex &, const QModelIndex &)), this, SLOT(SelectionChanged(const QModelIndex &, const QModelIndex &)));

    connect(tabWidget, SIGNAL(currentChanged(int)), this, SLOT(CurrentTabChanged(int)));
    
    connect(treeView, SIGNAL(doubleClicked(const QModelIndex&)), this, SLOT(SelectionDoubleClicked(const QModelIndex&)));
    
    connect(treeView, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(onCustomContextMenu(const QPoint &)));
    
    selectionFromTreeView = false;
}

FileWindow::TextFiles::iterator FileWindow::GetTextFileFromTabIndex(int index) {
    for (TextFiles::iterator it = textFiles.begin(); it!=textFiles.end(); ++it) {
        if (it->second->GetTabIndex() == index) {
           return it;
        }
    }
    return textFiles.end();
}

void FileWindow::ProjectChanged(Nano::Property<Context*, Project*>::EventData e) {
    
    Context* context = e.owner;
    
    if (!context->CurrentProject) {
        //treeView->setModel(0);
        return;
    }
    
    Project* project = context->CurrentProject;
    
    QDir path(project->path);
    
    if (!path.isReadable()) {
        //treeView->setModel(0);
        return;
    }
    
    QString absolutePath = path.absolutePath();
    
    fileSystemModel->setRootPath(absolutePath);
    
    treeView->setRootIndex(fileSystemModel->index(absolutePath));
}

void FileWindow::OnSave() {
    bool isTreeViewActive = treeView->hasFocus();
    bool isTabPageActive = tabWidget->currentWidget() ? tabWidget->currentWidget()->hasFocus() : false;
    if (!isTreeViewActive && !isTabPageActive) return;
    
    //std::cout<<"isTabWidgetActive: "<<isTabWidgetActive<<"  isTreeViewActive:"<<isTreeViewActive<<"  isTabPageActive:"<<isTabPageActive<<std::endl;
    
    TextFiles::iterator textFileToSave = GetTextFileFromTabIndex(tabWidget->currentIndex());
    if (textFileToSave!=textFiles.end()) {
        textFileToSave->second->Save();
    }
}

void FileWindow::SelectionChanged(const QModelIndex &current, const QModelIndex &previous) {
    
}

void FileWindow::OpenTextFile(QString filename) {
    TextFiles::iterator it = textFiles.find(filename);
    if (it==textFiles.end()) {
        TextFile* textFile = new TextFile();
        textFile->Create(tabWidget, filename);
        textFiles[filename] = textFile;
        it = textFiles.find(filename);
    }
    tabWidget->setCurrentIndex(it->second->GetTabIndex());
}

void FileWindow::FileRenamed(const QString &path, const QString &oldName, const QString &newName) {

    QString oldPathName = QDir(path).filePath(oldName);
    QString newPathName = QDir(path).filePath(newName);
    
    qDebug() << "FileRenamed path:" << path << " | oldName:"<< oldPathName << " | newName:"<<newPathName;


    TextFiles::iterator textFileToChange = textFiles.find(oldPathName);
    
    if (textFileToChange==textFiles.end()) return; //text file not opened

    TextFile* textFile = textFileToChange->second;
    textFiles.erase(textFileToChange);
    
    textFiles[newPathName]=textFile;
    textFile->ChangeFilename(newPathName);
}

void FileWindow::TabClosedClicked(int index) {

    TextFiles::iterator textFileToClose = GetTextFileFromTabIndex(index);
    if (textFileToClose!=textFiles.end()) {
        if(textFileToClose->second->Close()) {
            delete textFileToClose->second;
            textFiles.erase(textFileToClose);
        }
    }
}

void FileWindow::CurrentTabChanged(int index) {

    if (selectionFromTreeView) return;

    TextFiles::iterator selectedTextFile = GetTextFileFromTabIndex(index);
    if (selectedTextFile == textFiles.end()) return;

    QModelIndex modelIndex = fileSystemModel->index(selectedTextFile->second->Path());
    if (!modelIndex.isValid()) return;
    
    treeView->selectionModel()->setCurrentIndex(modelIndex, QItemSelectionModel::ClearAndSelect);
}

void FileWindow::SelectionDoubleClicked(const QModelIndex& current) {
    
    if (fileSystemModel->isDir(current)) {
        return;
    }
    QString filename = fileSystemModel->filePath(current);
    selectionFromTreeView = true;
    OpenTextFile(filename);
    selectionFromTreeView = false;

}

void FileWindow::CreateContextMenu() {
    contextMenu = new QMenu(treeView);
    menuRename = new QAction(QString("Rename"), treeView);
    contextMenu->addAction(menuRename);
    
}

void FileWindow::onCustomContextMenu(const QPoint &point) {
    QModelIndex index = treeView->indexAt(point);
    if (index.isValid()) {
    
        QAction* action = contextMenu->exec(treeView->mapToGlobal(point + QPoint(0,20)));
        
        if (action == menuRename) {
            treeView->edit(index);
        }
        
    }
}

